﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Bilibili.Common;
using Bilibili.Common.Database;
using Bilibili.Common.Log;
using Bilibili.Model.Live;
using Bilibili.Model.Resource;
using Newtonsoft.Json.Linq;
using PCLUntils.Json;
using PCLUntils.Objects;

namespace Bilibili.WebClient.Api
{
    public sealed class LiveCenterClient : ClientBase
    {
        public async Task<ReturnModel<JObject>> CancelMedal()
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("http://live.bilibili.com/AppUser/canelMedal", true);
                string results = await ApiClient.GetResults(apiInfo);
                var m = results.ToJObject();
                return BuildSuccessResult(m);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<JObject>(ex);
            }
        }
        public async Task<ReturnModel<JObject>> WearMedal(int id)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("http://live.bilibili.com/AppUser/wearMedal", true);
                string results = await ApiClient.PostResults(apiInfo, $"medal_id={id}&");
                var m = results.ToJObject();
                return BuildSuccessResult(m);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<JObject>(ex);
            }
        }
        public async Task<ReturnModel<LiveTitleModel>> GetUserTitle()
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://api.live.bilibili.com/appUser/myTitleList", "&actionKey=appkey&scale=hdpi", true);
                string results = await ApiClient.GetResults(apiInfo);
                LiveTitleModel m = results.ParseObject<LiveTitleModel>();
                return BuildSuccessResult(m);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<LiveTitleModel>(ex);
            }
        }
        public async Task<ReturnModel<LiveMedalModel>> GetMedals()
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://api.live.bilibili.com/AppUser/medal", "&actionKey=appkey", true);
                string results = await ApiClient.GetResults(apiInfo);
                LiveMedalModel m = results.ParseObject<LiveMedalModel>();
                return BuildSuccessResult(m);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<LiveMedalModel>(ex);
            }
        }
        public async Task<ReturnModel<List<LivingModel>>> GetLiveList()
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://api.live.bilibili.com/xlive/app-interface/v1/relation/liveAnchor", "&actionKey=appkey&qn=0&sortRule=0&filterRule=0", true);
                var results = await ApiClient.GetResults(apiInfo);
                var model = results.ToDynamicJObject();
                if (model.IsNotEmpty())
                {
                    if (model.Code == 0)
                    {
                        List<LivingModel> m = model.Json["data"]["rooms"].ToObject<List<LivingModel>>();
                        return BuildSuccessResult(m);
                    }
                    else
                        return BuildFailedResult<List<LivingModel>>(model.Message);
                }
                else
                    return BuildFailedResult<List<LivingModel>>();
            }
            catch (Exception ex)
            {
                LogManager.Instance.LogError("GetLiveList", ex);
                return BuildExceptionResult<List<LivingModel>>(ex);
            }
        }
        public async Task<ReturnModel<LiveUserInfoModel>> GetUserInfo()
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://api.live.bilibili.com/mobile/getUser", "&actionKey=appkey", true);
                var results = await ApiClient.GetResults(apiInfo);
                var model = results.ToDynamicJObject();
                if (model.IsNotEmpty())
                {
                    if (model.Code == 0)
                    {
                        if (SettingHelper.UserInfo.IsEmpty())
                            await new UserClient().GetUserInfo(SettingHelper.UserID, true);
                        LiveUserInfoModel m = model.Json["data"].ToObject<LiveUserInfoModel>();
                        m.uname = SettingHelper.UserInfo.Data.Card.Name;
                        m.face = SettingHelper.UserHead;
                        return BuildSuccessResult(m);
                    }
                    else
                        return BuildFailedResult<LiveUserInfoModel>(model.Message);
                }
                else
                    return BuildFailedResult<LiveUserInfoModel>();
            }
            catch (Exception ex)
            {
                LogManager.Instance.LogError("GetUserInfo", ex);
                return BuildExceptionResult<LiveUserInfoModel>(ex);
            }
        }
        public async Task<ReturnModel<List<NotLivingModel>>> GetUnLiveList(int page)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://api.live.bilibili.com/xlive/app-interface/v1/relation/unliveAnchor", $"&actionKey=appkey&page={page}&pagesize=20", true);
                var results = await ApiClient.GetResults(apiInfo);
                var model = results.ToDynamicJObject();
                if (model.IsNotEmpty())
                {
                    if (model.Code == 0)
                    {
                        var data = (JObject)model.Json["data"];
                        if (data.ContainsKey("rooms"))
                        {
                            List<NotLivingModel> m = data["rooms"].ToObject<List<NotLivingModel>>();
                            return BuildSuccessResult(m);
                        }
                        else
                            return BuildFailedResult<List<NotLivingModel>>();
                    }
                    else
                        return BuildFailedResult<List<NotLivingModel>>(model.Message);
                }
                else
                    return BuildFailedResult<List<NotLivingModel>>();
            }
            catch (Exception ex)
            {
                LogManager.Instance.LogError("GetUnLiveList", ex);
                return BuildExceptionResult<List<NotLivingModel>>(ex);
            }
        }
        public async Task<ReturnModel<List<LiveHistoryItemModel>>> GetHistory(int pageIndex)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://app.bilibili.com/x/v2/history/liveList", $"&actionKey=appkey&scale=hdpi&pn={pageIndex}&ps=20", true);
                string results = await ApiClient.GetResults(apiInfo);
                var jobj = results.ToJObject();
                if (jobj.ContainsKey("data"))
                {
                    var m = jobj["data"].ToObject<List<LiveHistoryItemModel>>();
                    return BuildSuccessResult(m);
                }
                else
                    return BuildFailedResult<List<LiveHistoryItemModel>>();
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<List<LiveHistoryItemModel>>(ex);
            }
        }
        public async Task<ReturnModel<AreaRoomList>> GetRoomList(string area_id, string parent_area_id, int page, string sort_type = "online")
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://api.live.bilibili.com/room/v3/Area/getRoomList", $"actionKey=appkey&area_id={area_id}&cate_id=0&page={page}&page_size=20&parent_area_id={parent_area_id}&qn=0&tag_version=1&sort_type={sort_type}", false);
                var results = await ApiClient.GetResults(apiInfo);
                var model = results.ToDynamicJObject();
                if (model.IsNotEmpty())
                {
                    if (model.Code == 0)
                    {
                        var m = model.Json["data"].ToObject<AreaRoomList>();
                        return BuildSuccessResult(m);
                    }
                    else
                        return BuildFailedResult<AreaRoomList>(model.Message);
                }
                else
                    return BuildFailedResult<AreaRoomList>();
            }
            catch (Exception ex)
            {
                LogManager.Instance.LogError("GetRoomList", ex);
                return BuildExceptionResult<AreaRoomList>(ex);
            }
        }
    }
}